module executor.message.server.TransferMsgExecutor;

import std.stdio;
import msgtrans;
import message.Constants;
import message.MsgDefine;
import google.protobuf;
import hunt.logging;
import std.array;
import hunt.util.Serialize;
import client.MsgServerClient;
import cache.ChatIdMap;
import client.GateServerClient;
import cache.UserStatusManager;
import client.LogicServerClient;
import hunt.httpclient;
import config.ConfigurationDefine;
import std.base64;
import hunt.http.HttpHeader;

static string getThumbnail(string objectName) //根据阿里云的objectName 生成微缩同二进制数据
{
    string ret;
    string[string] headers;
    string url = "http://" ~ Config.getInstance().getConfig().bucketName ~ "." ~ Config.getInstance().getConfig().ossEndpoint ~ "/" ~ objectName ~ "?x-oss-process=image/resize,l_100,m_lfit";
    auto response = Http.withHeaders(headers).get(url);
    logInfof("url : %s" ,url);
    if(response.isOk())
    {
        logInfof("thumbnail head: %s" ,response.header(HttpHeader.CONTENT_LENGTH.toString()));
        logInfof("thumbnail before: %s" ,response.content.length);
        ret = Base64.encode(cast(ubyte[])response.content);
    }
    return ret;
}

@TransportServer(MsgServerName)
class TransferMsgExecutor : AbstractExecutor!(TransferMsgExecutor){

    @MessageId(MESSAGE.CMD_MESSAGE_TRANSFER)
    void sendMsg(TransportContext ctx, MessageBuffer buffer) {
        auto req = new Msg();
        buffer.data.fromProtobuf!Msg(req);
        logInfo("ws-gate server forward msg to msg server : ",toJson(req));
        // if(req.type == MsgType.PICTURE && req.ossObjectName.length > 0) //如果是图片生成二进制数据
        // {
        //     req.binaryBase64 = getThumbnail(req.ossObjectName);
        //     logInfo("thumbnail length :" , req.binaryBase64.length);
        // }

        string [string] clients = ChatIdMap.getInstance().getGroupInfo(req.chatId);
        if(clients.length == 0) //如果对方已经不是你的好友,发送notice消息告知
        {
            auto msg = new Msg;
            msg.chatId = req.chatId;
            msg.fromUserId = req.fromUserId;
            msg.message = req.fromUserId;
            msg.msgTime = req.msgTime;
            msg.type = MsgType.NOTICE_MSG_BACKOFF;
            msg.localId = req.fromUserId;
            msg.messageId = req.messageId;
            ctx.session.send(new MessageBuffer(MESSAGE.CMD_MESSAGE_TRANSFER, msg.toProtobuf.array));
        }

        // forward msg to another
        
        logInfo("----%s",clients);
        foreach(string clientId ; clients)
        {
            MessageTransportClient client = MsgServerClient.getInstance.getForwardClient(clientId);
            logInfo("id: %s",clientId);
            logInfo("size: %d",MsgServerClient.getInstance.getSize);
            req.localId = clientId;
            if (client is null) //hash到本机
            {
                logInfo("clientId local: %s",clientId );
                if (UserStatusManager.getInstance().getUserStatus(clientId))
                {
                    // 获取所有 GateServer
                    TransportSession[ulong] contexts = GateServerClient.getInstance.getAllClient();
                    foreach(TransportSession c; contexts)
                    {
                        logInfo("222222");
                        c.send(new MessageBuffer(MESSAGE.CMD_MESSAGE_TRANSFER, req.toProtobuf.array));
                    }
                }
                else //不在线将消息发送给logiceserver 存库
                {
                    MessageTransportClient logicClient = LogicServerClient.getInstance().getForwardClient();
                    logicClient.send(new MessageBuffer(MESSAGE.CMD_PUT_UNRECEIVE, req.toProtobuf.array));
                }
            }
            else //chatId命中到了其他的msgserver上 转发过去
            {
                //buffer.id = MESSAGE.CMD_MESSAGE_TRANSFER_HASH;
                logInfo("clientId other server: %s",clientId );
                client.send(new MessageBuffer(MESSAGE.CMD_MESSAGE_TRANSFER_HASH,req.toProtobuf.array));
            }
            MessageTransportClient logicClient = LogicServerClient.getInstance().getForwardClient();
            logicClient.send(new MessageBuffer(MESSAGE.CMD_PUT_HISTORY_MSG,req.toProtobuf.array));
        }
    }

    @MessageId(MESSAGE.CMD_MESSAGE_TRANSFER_HASH)
    void sendMsgHash(TransportContext ctx, MessageBuffer buffer) {
        auto req = new Msg();
        buffer.data.fromProtobuf!Msg(req);
        //logInfo("ws-gate server forward msg to msg server : ",toJson(req));
        string clientId = req.localId;
        //TODO 用户是否在线列表如果在线如下，如果不在线，消息入库，continue , 后续需要加入ack 防止数据丢失
        if (UserStatusManager.getInstance().getUserStatus(clientId))
        {
            logInfo("CMD_MESSAGE_TRANSFER_HASH online %s" , clientId);
            TransportSession[ulong] contexts = GateServerClient.getInstance.getAllClient();
            foreach(TransportSession c ; contexts)
            {
                //buffer.id = MESSAGE.CMD_MESSAGE_TRANSFER;
                c.send(new MessageBuffer(MESSAGE.CMD_MESSAGE_TRANSFER,req.toProtobuf.array));
            }
        }else
        {
            logInfo("CMD_MESSAGE_TRANSFER_HASH offline %s" , clientId);
            MessageTransportClient logicClient = LogicServerClient.getInstance().getForwardClient();
            logicClient.send(new MessageBuffer(MESSAGE.CMD_PUT_UNRECEIVE,req.toProtobuf.array));
        }
    }

    @MessageId(MESSAGE.CMD_SET_MSG_READ_REQ)
    void getMsgReadREQ(TransportContext ctx, MessageBuffer buffer) {
        auto req = new AlreadyReadREQ();
        buffer.data.fromProtobuf!AlreadyReadREQ(req);

        string [string] clients = ChatIdMap.getInstance().getGroupInfo(req.chatId);

        if(clients.length != 2)
        {
                logError("friend only! clientId != 2");
                return;
        }

        foreach(string clientId ; clients)
        {
                if(clientId != req.clientId)
                {
                        if (UserStatusManager.getInstance().getUserStatus(clientId))
                        {
                            TransportSession[ulong] contexts = GateServerClient.getInstance.getAllClient();
                            req.clientId = clientId;
                            foreach(TransportSession c ; contexts)
                            {
                                c.send(new MessageBuffer(MESSAGE.CMD_SET_MSG_READ_RES,req.toProtobuf.array));
                            }
                            MessageTransportClient logicClient = LogicServerClient.getInstance().getForwardClient();
                            logicClient.send(new MessageBuffer(MESSAGE.CMD_SET_MSG_READ_REQ,req.toProtobuf.array));
                        }
                }
        }
    }
}

